package com.mcc.framework.config;

import org.springframework.util.ClassUtils;
import springfox.documentation.RequestHandler;

import java.lang.annotation.Annotation;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Predicate;

public class CustomRequestHandlerSelectors {

    //分隔符
    private static final String separator = ";";

    private CustomRequestHandlerSelectors() {
        throw new UnsupportedOperationException();
    }

    public static Predicate<RequestHandler> any() {
        return (each) -> {
            return true;
        };
    }

    public static Predicate<RequestHandler> none() {
        return (each) -> {
            return false;
        };
    }

    public static Predicate<RequestHandler> withMethodAnnotation(final Class<? extends Annotation> annotation) {
        return (input) -> {
            return input.isAnnotatedWith(annotation);
        };
    }

    public static Predicate<RequestHandler> withClassAnnotation(final Class<? extends Annotation> annotation) {
        return (input) -> {
            return (Boolean) declaringClass(input).map(annotationPresent(annotation)).orElse(false);
        };
    }

    private static Function<Class<?>, Boolean> annotationPresent(final Class<? extends Annotation> annotation) {
        return (input) -> {
            return input.isAnnotationPresent(annotation);
        };
    }

    private static Function<Class<?>, Boolean> handlerPackage(final String basePackage) {
        return (input) -> {
            // 循环判断匹配
            for (String strPackage : basePackage.split(separator)) {
                if (ClassUtils.getPackageName(input).startsWith(strPackage)) {
                    return true;
                }
            }
            return false;
        };
    }

    public static Predicate<RequestHandler> basePackage(final String basePackage) {
        return (input) -> {
            return (Boolean) declaringClass(input).map(handlerPackage(basePackage)).orElse(true);
        };
    }

    private static Optional<? extends Class<?>> declaringClass(RequestHandler input) {
        return Optional.ofNullable(input.declaringClass());
    }
}
